#include "tim.h"
#include "math.h"
#include "string.h"
#include "beep.h"
#include "schedule.h"

//https://zhidao.baidu.com/question/1929397911420653787.html
short tone[] = { 0,
		262,  294,  330,  349,  392,  440,  494,
		523,  587,  659,  698,  784,  880,  988,
		1047, 1175, 1319, 1397, 1568, 1760, 1967
};

short musicShenHua[]={
		L0,4,
		L6,4,M3,4,L7,8,L0,2,
		L6,2,M1,2,M2,3, M1,1,M3,8,L0,2,
		L6,4,M6,4,M5,2,M6,2,M5,2,M2,2,M3,1,M4,2,M3,13,L0,6,
		L6,4,M6,4,M5,2,M2,2,M3,2,M4,2,M3,8,M1,8,L0,2,
		L6,4,M3,4,M2,6,L7,4,L6,16,L0,8,

		L6,4,M3,4,L7,8,L0,2,
		L6,2,M1,2,M2,3, M1,1,M3,8,L0,2,
		L6,4,M6,4,M5,2,M6,2,M5,2,M2,2,M3,1,M4,2,M3,13,L0,6,
		L6,4,M6,4,M5,1,M2,1,M3,3,M4,3,M3,4,M2,4,M1,8,L0,2,
		L6,4,M3,4,M2,6,L7,4,L6,12,L0,8,

		L6,2,L7,2,M1,2,M2,2,M3,2,M1,2,L7,4,L5,4, L0,1, L6,2,M1,2,M2,3,M3,3,M3,4,L0,2,
		L6,2,L7,2,M1,2,M2,2,M3,2,M1,2,L7,4,L5,4, L0,1, L6,2,M1,2,M2,3,L7,3,M1,4,L0,2,
		L6,2,L7,2,M1,2,M2,2,M3,2,M1,2,L7,4,L5,4, L0,1, L6,2,M1,2,M2,3,M3,3,M3,4,L0,2,
		L6,2,L7,2,M1,2,M2,2,M3,2,M1,2,L7,4,L5,4, L0,1, L6,2,M1,2,M2,3,L7,3,M1,4,L0,2,

		M1,1,M1,1,M2,2,M3,2,M1,2,L7,4,L5,4, M1,4,L7,4,L5,6, L0,1, L7,4,L6,8,L0,8,
		L0,1,L0,1,
};

struct ToneNode *pCurMusic = NULL;
struct ToneNode *pCurTone = NULL;

// 时钟频率为72000000
// arr为72 - 1，// cnt为36，占空比稳定在50%
// 根据arr调整频率，freq = SysFreq / (arr + 1) / (psc + 1)
// 所以psc = SysFreq / (arr + 1) / freq - 1
//        = 72000000 / 72 / freq - 1
//        = 1000000 / freq - 1
// 因为psc是short类型，所以最低频率为20Hz
void Beep_SetFreq(int freq)
{
	static int oldFreq = 0;

	if (20 <= freq && freq <= 20000)
	{
		__HAL_TIM_PRESCALER(&htim4, 1000000 / freq - 1);
	}

	if (0 == freq)
	{
		HAL_TIM_PWM_Stop(&htim4,TIM_CHANNEL_3);
	}
	else if(0 == oldFreq && 0 != freq)
	{
		HAL_TIM_PWM_Start(&htim4,TIM_CHANNEL_3);
	}
	oldFreq = freq;
}

void Beep_PlayTone(short toneIdx)
{
	if (toneIdx < 0 || 27 < toneIdx)
	{
		return ;
	}
	// 输入27，输出高音7
	toneIdx = toneIdx / 10 * 7 + toneIdx % 10;
	Beep_SetFreq(tone[toneIdx]);
}
// 定时调用，调用周期为单位节拍周期
void Beep_PlayMusic(short musicIdx)
{
	if (NULL == pCurMusic)
	{
		pCurMusic = (struct ToneNode *)musicShenHua;
		pCurTone = pCurMusic;
	}

	static short toneLen = 0;
	if (toneLen > pCurTone->len)
	{
		toneLen = 0;
		++pCurTone;
		if (0 == (pCurTone-1)->tone
			&& 0 == pCurTone->tone)
		{
			pCurTone = pCurMusic;
		}
	}
	Beep_PlayTone(pCurTone->tone);
	++toneLen;
}


// 测试呼吸灯
//void Task10ms()
//{
//	int breathTime = 4000;
//	int interval = 10;
//	/// 期望3秒为周期，此函数每10毫秒，那么执行300次，数值需要增大到6.28，每次增加6.28 / 300
//	static float cnt = 0;
//	cnt += (6.28f / (breathTime / interval));
//	int value = sin(cnt) * 500 + 500;
//	__HAL_TIM_SetCompare(&htim2, TIM_CHANNEL_2, value);
//}
